

import { mergeOptions } from '../util/options'
import { initRender } from './render'
import { initLifecycle,callHook } from './lifecycle'
import { initState } from './state'
import { initEvents } from './event'

let uid = 0
export function initMixin(Vue) {
    Vue.prototype._init = function (options) {
        const vm = this
        vm._uid = uid++
        vm._isVue = true //用于observe判断当前为vue实例不可劫持
        if (options && options._isComponent) {
            initInternalComponent(vm, options)
        } else {
            vm.$options = mergeOptions(vm.constructor.options, options || {}, vm)
        }
        callHook(vm, 'beforeCreate')
        initLifecycle(vm)
        initEvents(vm)
        initRender(vm)
        initState(vm)

        callHook(vm, 'created')

        if (vm.$options.el) {
            vm.$mount(vm.$options.el)
        }

    }
}


function initInternalComponent(vm, options){
  const opts = vm.$options = Object.create(vm.constructor.options) //配置项目,create-component - init方法创建
  // 当前组件在父级的tag标签vnode
  const parentVnode = options._parentVnode 
  opts._parentVnode = parentVnode
  // 当前组件的父级
  opts.parent = options.parent

  const vnodeComponentOptions = parentVnode.componentOptions
  opts.propsData = vnodeComponentOptions.propsData
  opts._renderChildren = vnodeComponentOptions.children
  opts._componentTag = vnodeComponentOptions.tag
  opts._parentListeners = vnodeComponentOptions.listeners

  if (options.render) {
    opts.render = options.render
    opts.staticRenderFns = options.staticRenderFns
  }
}